package org.abc.fund.service.funds;

import org.abc.fund.dto.FundBasicInfoDTO;
import org.abc.fund.dto.FundCompanyDTO;
import org.abc.fund.entity.funds.FundBasicInfo;
import org.abc.fund.entity.funds.FundCompany;
import org.abc.fund.entity.funds.FundTagRelation;
import org.abc.fund.repository.funds.FundBasicInfoRepository;
import org.abc.fund.repository.funds.FundCompanyRepository;
import org.abc.fund.repository.funds.FundTagRelationRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class FundCompanyService {

    @Autowired
    private FundCompanyRepository fundCompanyRepository;

    @Autowired
    private FundBasicInfoRepository fundBasicInfoRepository;

    @Autowired
    private FundTagRelationRepository fundTagRelationRepository;

    // ✅ 获取所有基金公司（可选关键词模糊查询）
    public List<FundCompany> getAllCompanies(String name) {
        if (name != null && !name.isBlank()) {
            return fundCompanyRepository.findByNameContaining(name);
        }
        return fundCompanyRepository.findAll();
    }

    // ✅ 分页获取基金公司 DTO
    public Page<FundCompanyDTO> getCompaniesDTOByPage(int page, int size, String keyword) {
        Pageable pageable = PageRequest.of(page, size, Sort.by("name").ascending());
        Page<FundCompany> companyPage = (keyword == null || keyword.isBlank())
                ? fundCompanyRepository.findAll(pageable)
                : fundCompanyRepository.findByNameContainingOrShortNameContaining(keyword, keyword, pageable);

        List<FundCompanyDTO> dtoList = companyPage.getContent().stream()
                .map(company -> new FundCompanyDTO(
                        company.getId(),
                        company.getName(),
                        company.getShortName(),
                        company.getRating(),
                        company.getFunds() != null ? company.getFunds().size() : 0,
                        null // 不加载基金列表
                ))
                .toList();

        return new PageImpl<>(dtoList, pageable, companyPage.getTotalElements());
    }

    // ✅ 标签筛选公司（DTO 列表）
    public List<FundCompanyDTO> getCompaniesByTags(List<String> tagNames) {
        if (tagNames == null || tagNames.isEmpty()) {
            return fundCompanyRepository.findAll().stream().map(this::toDTO).toList();
        }

        // 查出有对应标签的基金代码
        List<FundTagRelation> relations = fundTagRelationRepository.findByTagNameIn(tagNames);
        Set<String> fundCodes = relations.stream()
                .map(FundTagRelation::getFundCode)
                .collect(Collectors.toSet());

        if (fundCodes.isEmpty()) return List.of();

        // 查出这些基金和对应公司
        List<FundBasicInfo> funds = fundBasicInfoRepository.findByCodeIn(new ArrayList<>(fundCodes));
        Set<FundCompany> companies = funds.stream()
                .map(FundBasicInfo::getCompany)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());

        return companies.stream().map(this::toDTO).toList();
    }

    // ✅ 获取公司详情（包含基金列表）
    public FundCompanyDTO getCompanyDetail(Long id) {
        FundCompany company = fundCompanyRepository.findById(id).orElse(null);
        if (company == null) return null;
        return toDTO(company);
    }

    // ✅ 获取某个公司旗下基金（用于展开）
    public List<FundBasicInfoDTO> getFundsByCompanyName(String companyName) {
        List<FundBasicInfo> funds = fundBasicInfoRepository.findByCompany_NameContaining(companyName);
        return funds.stream().map(this::toFundDTO).toList();
    }

    // ➕ 新增基金公司
    public FundCompany addCompany(FundCompany company) {
        return fundCompanyRepository.save(company);
    }

    // ✏️ 修改基金公司
    public FundCompany updateCompany(Long id, FundCompany updated) {
        return fundCompanyRepository.findById(id).map(company -> {
            company.setName(updated.getName());
            company.setShortName(updated.getShortName());
            company.setRating(updated.getRating());
            return fundCompanyRepository.save(company);
        }).orElse(null);
    }

    // ❌ 删除
    public void deleteCompany(Long id) {
        fundCompanyRepository.deleteById(id);
    }

    // 🔍 获取单个实体
    public FundCompany getCompanyById(Long id) {
        return fundCompanyRepository.findById(id).orElse(null);
    }

    // ✅ 实体转 DTO
    private FundCompanyDTO toDTO(FundCompany company) {
        List<FundBasicInfoDTO> fundDTOs = company.getFunds() != null
                ? company.getFunds().stream().map(this::toFundDTO).toList()
                : List.of();

        return new FundCompanyDTO(
                company.getId(),
                company.getName(),
                company.getShortName(),
                company.getRating(),
                company.getFunds() != null ? company.getFunds().size() : 0,
                fundDTOs
        );
    }

    // ✅ 基金实体转 DTO
    private FundBasicInfoDTO toFundDTO(FundBasicInfo f) {
        return new FundBasicInfoDTO(
                f.getCode(),
                f.getName(),
                f.getType(),
                f.getStatus(),
                f.getLatestNav(),
                f.getLatestNavDate(),
                f.getLatestEstNav(),
                f.getLatestEstRate(),
                f.getManager() != null ? f.getManager().getName() : "",
                f.getCompany() != null ? f.getCompany().getName() : ""
        );
    }
}
